package com.example.springframeworklearning.config;

import com.example.springframeworklearning.converter.MapToOrderConverter;
import com.example.springframeworklearning.converter.StringOrderStatusConverterFactory;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.format.AnnotationFormatterFactory;
import org.springframework.format.annotation.DateTimeFormat;
import org.springframework.format.datetime.DateTimeFormatAnnotationFormatterFactory;
import org.springframework.format.datetime.standard.DateTimeFormatterRegistrar;
import org.springframework.format.support.FormattingConversionServiceFactoryBean;

import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;

/**
 * @author luo
 * @since 2022/9/21 11:36
 */
@Configuration
public class FormattingConversionServiceFactoryConfig {


    /**
     * FormattingConversionServiceFactoryBean 是一个 FactoryBean
     * 其调用 FactoryBean::getObject 会得到一个 FormattingConversionService
     * FormattingConversionService 继承了 ConversionService 的功能
     * 所以 这里 声明了 FormattingConversionServiceFactoryBean 之后
     * ConversionServiceFactoryBean 就不用再配置了
     * <p>
     * 这里侧面应证了：如果往ioc中放入的是 FactoryBean 对象
     * 那么FactoryBean::getObject 拿到 bean 的名字就是此方法的名称
     *
     * @return
     */
    @Bean
    public FormattingConversionServiceFactoryBean converterService(StringOrderStatusConverterFactory stringOrderStatusConverterFactory) {

        FormattingConversionServiceFactoryBean result = new FormattingConversionServiceFactoryBean();

        HashSet<Object> converterSet = new HashSet<>(
                Arrays.asList(
//                注册 converter
                        new MapToOrderConverter(),
//                注册 converterFactory
                        stringOrderStatusConverterFactory
                )
        );
//        把所有的 converter 注册到 ConversionServiceFactoryBean 中
        result.setConverters(converterSet);

        /* 添加基于注解的日期格式化器
         * DateTimeFormatAnnotationFormatterFactory 仅对 Long Date Calendar 类型字段上的 @DateTimeFormat 有效
         * 不支持 LocalDateFormatter
         * AnnotationFormatterFactory 接口是 Formatter 的增强版
         * Formatter 只能进行 解析和 toString
         * AnnotationFormatterFactory 可能根据 注解 和属性类型来 决定是否要执行 解析和 toString
         */
        AnnotationFormatterFactory<DateTimeFormat> dateTimeFormatAnnotationFormatterFactory = new DateTimeFormatAnnotationFormatterFactory();

        result.setFormatters(new HashSet<>(Arrays.asList(dateTimeFormatAnnotationFormatterFactory)));


        // 全局配置日期格式化（但是没有效果）
        DateTimeFormatterRegistrar registrar = new DateTimeFormatterRegistrar();
        registrar.setDateFormatter(DateTimeFormatter.ISO_TIME);

        result.setFormatterRegistrars(new HashSet<>(Collections.singleton(registrar)));
        return result;
    }
}
